package com.zzyl.nursing.service.impl;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.common.constant.CacheConstants;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.dto.DeviceDataPageReqDto;
import com.zzyl.nursing.dto.IotMsgNotifyData;
import com.zzyl.nursing.dto.IotMsgService;
import com.zzyl.nursing.service.IDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.service.IDeviceDataService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 设备数据Service业务层处理
 * 
 * @author liushaoxu
 * @date 2025-06-18
 */
@Service
@Slf4j
public class DeviceDataServiceImpl extends ServiceImpl<DeviceDataMapper, DeviceData> implements IDeviceDataService
{
    @Autowired
    private DeviceDataMapper deviceDataMapper;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询设备数据
     * 
     * @param id 设备数据主键
     * @return 设备数据
     */
    @Override
    public DeviceData selectDeviceDataById(Long id)
    {
        return deviceDataMapper.selectById(id);
    }

    @Override
    public List<DeviceData> selectDeviceDataList(DeviceDataPageReqDto dto) {
        return lambdaQuery()
                .eq(StrUtil.isNotBlank(dto.getDeviceName()), DeviceData::getDeviceName, dto.getDeviceName())
                .eq(StrUtil.isNotBlank(dto.getFunctionId()), DeviceData::getFunctionId, dto.getFunctionId())
                .between(dto.getStartTime()!=null &&dto.getEndTime()!=null, DeviceData::getAlarmTime, dto.getStartTime(),dto.getEndTime() )
                .list();
    }

   /* *//**
     * 查询设备数据列表
     *
     * @param deviceData 设备数据
     * @return 设备数据
     *//*
    @Override
    public List<DeviceData> selectDeviceDataList(DeviceData deviceData)
    {
        return deviceDataMapper.selectDeviceDataList(deviceData);
    }*/

    /**
     * 新增设备数据
     * 
     * @param deviceData 设备数据
     * @return 结果
     */
    @Override
    public int insertDeviceData(DeviceData deviceData)
    {
        return deviceDataMapper.insert(deviceData);
    }

    /**
     * 修改设备数据
     * 
     * @param deviceData 设备数据
     * @return 结果
     */
    @Override
    public int updateDeviceData(DeviceData deviceData)
    {
        return deviceDataMapper.updateById(deviceData);
    }

    /**
     * 批量删除设备数据
     * 
     * @param ids 需要删除的设备数据主键
     * @return 结果
     */
    @Override
    public int deleteDeviceDataByIds(Long[] ids)
    {
        return deviceDataMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除设备数据信息
     * 
     * @param id 设备数据主键
     * @return 结果
     */
    @Override
    public int deleteDeviceDataById(Long id)
    {
        return deviceDataMapper.deleteById(id);
    }

    /**
     * 批量插入设备数据
     * @param data
     */
    @Override
    public void batchInsertDeviceData(IotMsgNotifyData data) {
        //我们最终的目标是把数据存储到device_data表中
        String deviceId = data.getHeader().getDeviceId();
        Device device = deviceService.lambdaQuery()
                .eq(Device::getIotId, deviceId)
                .one();
        if (device == null){
            //说明设备不存在
            log.error("设备不存在");
            return;
        }
        //先去查设备
        List<IotMsgService> services = data.getBody().getServices();
        ArrayList<DeviceData> ddList = new ArrayList<>();
        for (IotMsgService service : services) {
            Map<String, Object> map = service.getProperties();
            String eventTime = service.getEventTime();
            //时间的类型转换

            // 定义输入格式
            DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");

            // 解析为OffsetDateTime
            OffsetDateTime offsetDateTime = OffsetDateTime.parse(eventTime, inputFormatter);

            // 转换为LocalDateTime
            LocalDateTime beijingTime = offsetDateTime.toLocalDateTime();
            map.forEach((key, value)->{
                DeviceData dd = new DeviceData();
                dd.setDeviceName(device.getDeviceName());
                dd.setIotId(deviceId);
                dd.setProductKey(device.getProductKey());
                dd.setProductName(device.getProductName());
                dd.setRemark(device.getRemark());
                dd.setLocationType(device.getLocationType());
                dd.setDeviceDescription(device.getDeviceDescription());
                dd.setPhysicalLocationType(device.getPhysicalLocationType());
                dd.setFunctionId(key);
                dd.setDataValue(value.toString());
                dd.setAlarmTime(beijingTime);
                ddList.add(dd);
            });
        }
        //插入设备数据
        saveBatch(ddList);

        //存储到redis中deviceDataList
        //hash 结构来进行存储  大key  小key  value
        redisTemplate.opsForHash().put(CacheConstants.IOT_DEVICE_LAST_DATA, deviceId, JSONUtil.toJsonStr(ddList));
    }
}
